package com.wanghang89.gmail.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpMessage;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

import com.wanghang89.gmail.util.IOHelper;

public class Downloader implements DownloaderConstants {
	
	private static HttpClient client = new DefaultHttpClient() ;
	
	private final static int REQUEST_TIMEOUT  = 30*000;//请求超时时间 单位:毫秒
	private final static int CONNECTION_TIMEOUT = 30*000;//连接超时时间 单位:毫秒
	
	private final static Logger LOGGER = Logger.getLogger(Downloader.class);
	
	static{
		HttpParams params = client.getParams();
		HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
		HttpConnectionParams.setSoTimeout(params, REQUEST_TIMEOUT);
	}
		
	public static Document downloadByGet(String url , String pageEncoding)
	{
		HttpGet get = new HttpGet(url);
		get.addHeader("CONTENT-TYPE","application/x-www-form-urlencoded;charset="+pageEncoding);
		get.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
		return execute(get,pageEncoding);
	}
	
	public static Document downloadByPost(String url , List<NameValuePair> parameters , String pageEncoding , String parameterEncoding)
	{
		HttpPost post = new HttpPost(url);
		post.addHeader("CONTENT-TYPE","application/x-www-form-urlencoded;charset="+pageEncoding);
		post.addHeader("User-Agent","Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)");
		if (parameters!=null&&!parameters.isEmpty()) {
			try {
				UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(parameters
						,parameterEncoding==null?EncodingConstants.UTF_8:parameterEncoding);
				post.setEntity(formEntity);
			} catch (Exception e) {
				LOGGER.error(e.getMessage());
			}
		}
		return execute(post,pageEncoding);
	}
	
	private static Document execute(HttpUriRequest request , String pageEncoding) 
	{
		boolean isTimeout = false;
		try {
			return doExecute(request,pageEncoding);
		} catch (SocketTimeoutException e) {
			isTimeout = true;
		} catch (ConnectTimeoutException e) {
			isTimeout = true;
		}
		if (isTimeout) {
			LOGGER.info("download timeout ,reload:"+request.getURI().toString());
			try {
				return doExecute(request,pageEncoding);
			} catch (SocketTimeoutException e) {
				LOGGER.error(e.getMessage());
			} catch (ConnectTimeoutException e) {
				LOGGER.error(e.getMessage());
			}
		}
		return null;
	}
	
	private static Document doExecute(HttpUriRequest request,String pageEncoding) throws SocketTimeoutException, ConnectTimeoutException
	{
		InputStream inStream = null;
		BufferedReader reader = null;
		HttpEntity entity = null;
		try {
			HttpResponse res = client.execute(request);
			int status = res.getStatusLine().getStatusCode();
			LOGGER.debug("status:" + status);
			if (status == HttpStatus.SC_OK) {
				entity = res.getEntity();
				if (entity != null) {
					LOGGER.debug(entity.getContentType());
					inStream = entity.getContent();
//					int length = inStream.available();
//					byte[] buffer = new byte[length];
//					inStream.read(buffer);
//					reader = new BufferedReader(
//							new InputStreamReader(inStream));
//					String line = null;
//					StringBuilder builder = new StringBuilder();
//					while ((line = reader.readLine()) != null) {
//						builder.append(line);
//					}
//					inStream.close();
//					reader.close();
					Document doc = Jsoup.parse(inStream,pageEncoding,"");
					return doc;
				}
			}
		}catch (SocketTimeoutException e) {
			throw e;
		}catch (ConnectTimeoutException e) {
			throw e;
		}catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}catch (Exception e) {
			e.printStackTrace();
		}finally{
			IOHelper.closeInputStream(inStream);
			IOHelper.closeReader(reader);
			request.abort();
		}
		return null;
	}
	
	public static void main(String[] args) {
		
	}

}
